package org.parakit;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;


public class ParaKitTaskExecutor {
	
	ConcurrentLinkedQueue<PriorityTask> highTasks = new ConcurrentLinkedQueue<PriorityTask> ();
	ConcurrentLinkedQueue<PriorityTask> mediumTasks = new ConcurrentLinkedQueue<PriorityTask> ();
	ConcurrentLinkedQueue<PriorityTask> lowTasks = new ConcurrentLinkedQueue<PriorityTask> ();
	
	Semaphore highSemaph = new Semaphore(0);
	Semaphore mediumSemaph = new Semaphore(0);
	Semaphore lowSemaph = new Semaphore(0);
	
	public void submitTask(PriorityTask task){
		switch (task.getTaskPriorityLevel()){
		case HIGH :
			highTasks.offer(task);
			highSemaph.release();
			mediumSemaph.release();
			lowSemaph.release();
			break;
		case MEDIUM :
			mediumTasks.offer(task);
			mediumSemaph.release();
			lowSemaph.release();
			break;
		case LOW :
			lowTasks.offer(task);
			lowSemaph.release();
			break;
		}
	}

	public void start(){
		//start threads for low/medium/high task.
		for (int i = 0;i<3 ; i++){
			Thread thread = new Thread(new Runnable(){

				@Override
				public void run() {
					
					while(true){
						try {
							lowSemaph.acquire();
							PriorityTask task = null;
							task = highTasks.poll();
							if (task == null) task = mediumTasks.poll();
							if (task == null) task = lowTasks.poll();
							if (task != null) task.run();
						} catch (InterruptedException e) {
							Thread.interrupted();
						}
					}
				}
				
			},"LOWTREAD" + i);
			thread.start();
			System.out.println("LOWTREAD" + i + " started");
		}

		//start threads for medium/high task.
		for (int i = 0;i<2 ; i++){
			Thread thread = new Thread(new Runnable(){

				@Override
				public void run() {
					
					while(true){
						try {
							mediumSemaph.acquire();
							PriorityTask task = null;
							task = highTasks.poll();
							if (task == null) task = mediumTasks.poll();
							if (task != null) task.run();
						} catch (InterruptedException e) {
							Thread.interrupted();
						}
					}
				}
				
			},"MEDIUMTREAD" + i);
			thread.start();
			System.out.println("MEDIUMTREAD" + i + " started");
		}
	
		//start threads for high task.
		for (int i = 0;i<1 ; i++){
			Thread thread = new Thread(new Runnable(){

				@Override
				public void run() {
					
					while(true){
						try {
							highSemaph.acquire();
							PriorityTask task = null;
							task = highTasks.poll();
							if (task != null) task.run();
						} catch (InterruptedException e) {
							Thread.interrupted();
						}
					}
				}
				
			},"HIGHTREAD" + i);
			thread.start();
			System.out.println("HIGHTREAD" + i + " started");
		}
	}
}
